<?php


namespace app\controller\api;


use app\common\model\StudentModel;
use app\common\service\redis\PoolRedis;
use app\model\AdminClass;
use app\model\AdminDormitory;
use app\model\AdminSchool;
use app\model\AdminStaff;
use app\model\AdminStaffDormitoryApply;
use app\model\AdminStaffIcCard;
use app\model\AdminStudentDormitory;
use app\util\ReturnCode;
use think\facade\Log;
use think\facade\Validate;
use think\Response;

class Dormitory extends Base
{

    public function classList(): Response {
        $school_id = input('get.school_id/d');
        $validate = Validate::rule([
            'school_id|学校'=>'require'
        ]);
        if (!$validate->check(input('get.'))) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }
        $class = AdminClass::where('is_delete', 0)->where('school_id', $school_id)
            ->order('name', 'asc')->field('id,name')->select()->toArray();
        return $this->buildSuccess($class);
    }

    /**
     * @func dynamicList
     * @method GET
     * @desc 1. 全部获取，参数仅需传type，值为0
     * 2. 单独获取学校，type传值1
     * 3. 级联动态获取，例：通过学校ID获取获取宿舍楼，type传值2，school_id必填；获取宿舍号，type传值3，school_id、dormitory_id必填
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @Time: 2021/12/7 17:42
     */
    public function dynamicList(): Response {
        $data = [];
        $type = input('get.type/d');// 0--全部 1--学校 2--宿舍楼 3--宿舍
        $school_id = input('get.school_id/d');
        $dormitory_id = input('get.dormitory_id/d');
        $keyword = input('get.keyword/s');
        $validate = Validate::rule([
            'type|错误的请求类型,' => 'require|in:0,1,2,3',
            'school_id|学校'=>'requireIf:type,2|requireIf:type,3',
            'dormitory_id|宿舍' => 'requireIf:type,3'
        ]);
        if (!$validate->check(input('get.'))) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }
        $sub_query = null;
        $uuid = input('get.uuid/s');
        if ($uuid) {
            if ($type == 2) {
                $sub_query = AdminStaffIcCard::alias('sc')
                    ->join('admin_staff s', 's.id=sc.staff_id')
                    ->where([
                        's.uuid' => $uuid,
                        'sc.school_id' => $school_id,
                        'sc.is_delete' => 0
                    ])->group('sc.dormitory_id')->field('sc.dormitory_id')->buildSql();
            }
            if ($type == 3) {
                $sub_query = AdminStaffIcCard::alias('sc')
                    ->join('admin_staff s', 's.id=sc.staff_id')
                    ->where([
                        's.uuid' => $uuid,
                        'sc.school_id' => $school_id,
                        'sc.dormitory_id' => $dormitory_id,
                        'sc.is_delete' => 0
                    ])->group('sc.student_dormitory_id')->field('sc.student_dormitory_id')->buildSql();
            }
        }
        if ($type == 1 || $type == 0) {
            $school = AdminSchool::where('is_delete', 0)
                ->order('sort_no', 'desc')->field('id,name');
            if ($keyword) $school = $school->whereLike('name', "%{$keyword}%");
            $data['school'] = $school->select()->toArray();
        }
        if ($type == 2 || $type == 0) {
            $dormitory = AdminDormitory::alias('ad')
                ->where('ad.is_delete', 0)
                ->order('ad.name', 'asc')
                ->field('ad.id,ad.name');
            if ($keyword) $dormitory = $dormitory->whereLike('ad.name', "%{$keyword}%");
            if ($type == 2) {
                $school_id && $dormitory = $dormitory->where('ad.school_id', $school_id);
                if ($sub_query) $dormitory = $dormitory->join([$sub_query => 's1'], 's1.dormitory_id=ad.id');
            }
            $data['dormitory'] = $dormitory->select()->toArray();
        }
        if ($type == 3 || $type == 0) {
            $student_dormitory = AdminStudentDormitory::alias('sd')
                ->where('sd.is_delete', 0)
                ->order('sd.name', 'asc')
                ->field('sd.id,sd.name,sd.uuid');
            if ($keyword) $student_dormitory = $student_dormitory->whereLike('sd.name', "%{$keyword}%");
            if ($type == 3) {
                if ($school_id && $dormitory_id) $student_dormitory = $student_dormitory->where('sd.school_id', $school_id)->where('sd.dormitory_id', $dormitory_id);
                if ($sub_query) $student_dormitory = $student_dormitory->join([$sub_query => 's1'], 's1.student_dormitory_id = sd.id');
            }
            $data['student_dormitory'] = $student_dormitory->select()->toArray();
        }
        return $this->buildSuccess($data);
    }

    /**
     * @func dormitoryNumberByBlue
     * @method POST
     * @desc 通过蓝牙deviceId获取匹配的宿舍号
     * @return Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @Time: 2021/12/9 18:08
     */
    public function dormitoryNumberByBlue(): Response {
        $validate = Validate::rule([
            'uuid|账号' => 'require',
        ]);
        if (!$validate->check(input('post.'))) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }
        $staff = AdminStaff::where([
            'is_delete' => 0,
            'status' => AdminStaff::AUDIT_PASS,
            'uuid' => input('post.uuid/s'),
        ])->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '账号不存在或未审核通过');
        }
        if ($staff->is_delete == 1) {
            return $this->buildFailed(ReturnCode::AUTH_ERROR, '账号已删除，请联系管理员');
        }
        if ($staff->type == 0 && $staff->expire_flag) {
            return $this->buildFailed(ReturnCode::AUTH_ERROR, '账号已过期，无法登录');
        }
        $stu_sub_query = AdminStudentDormitory
            //::cache(true,60)
            ::where('is_delete', 0)
            ->field('id,name student_dormitory_name,uuid,door_type');
        $deviceIds = input('post.deviceIds/s');
        if ($deviceIds){
            $stu_sub_query->where('uuid', 'in', $deviceIds);
        }
        $stu_sub_query = $stu_sub_query->buildSql();
        $result = AdminStaffIcCard::alias('card')
            ->join([$stu_sub_query => 'sd'], 'sd.id=card.student_dormitory_id')
            ->where([
                'card.is_delete' => 0,
                'card.staff_id' => $staff->id,
                'card.school_id' => $staff->school_id
            ])->with('dormitory')
            ->append(['lock_permission_arr'])
            ->hidden(['school_id','create_time','update_time','is_delete'])
            ->select()->toArray();

        foreach ($result as $key => $item) {
            //$result[$key]['sim_uid'] = $staff->sim_card;
            $result[$key]['max_no'] = AdminStudentDormitory::getKDCardNumberMax($item['door_type']); // 阔道最大卡片编号
            // 阔道门锁自己连接没有IC和SIM卡不分配
            if ((empty($result[$key]['ic_card']) || $result[$key]['ic_card']=='00000000')
                && (empty($result[$key]['sim_uid']) || $result[$key]['sim_uid']=='00000000000000000000')) {
                $result[$key]['student_dormitory_no'] = -1;
            } else {
                $result[$key]['student_dormitory_no'] = (int)AdminStudentDormitory::dynamicDistribution($staff->toArray(),$item['id'],$item['door_type']);
                Log::error('dynamicDistribution :'.$staff->id.' | 姓名:'.$staff->name.' | 宿舍号:'.$item['student_dormitory_name'].' | '.$item['door_type'].' | 分配编号:'.$result[$key]['student_dormitory_no'].' | IC:'.$result[$key]['ic_card'].' | SIM:'.$result[$key]['sim_uid']);
            }
            $result[$key]['offline_pwd_factor'] = '';
            $result[$key]['online_pwd'] = [];
            if ($item['lock_permission']) {
                $result[$key]['lock_permission_arr'] = array_map(function ($i) {
                    return (int)$i;
                }, explode(',', $item['lock_permission']));
            }
            unset($result[$key]['lock_permission']);
        }
        return $this->buildSuccess($result);
    }

    public function dormitoryApplyGet() : Response
    {
        $validate = Validate::rule([
            'uuid|用户' => 'require'
        ]);
        if (!$validate->check(input('get.'))) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }
        $staff = AdminStaff::where([
            'is_delete' => 0,
            'status' => AdminStaff::AUDIT_PASS,
            'uuid' => input('get.uuid/s'),
        ])->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '账号不存在或未审核通过');
        }
        if ($staff->type == 0 && $staff->expire_flag) {
            return $this->buildFailed(ReturnCode::AUTH_ERROR, '账号已过期，无法登录');
        }
        $dormitoryApply = AdminStaffDormitoryApply::with(['staff', 'school', 'dormitory', 'student', 'oldDormitory', 'oldStudent'])
            ->order(['apply_time' => 'DESC'])
            ->where([
            'staff_id' => $staff->id
        ])->find();
        if (!$dormitoryApply){
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '不存在申请记录');
        }
        return $this->buildSuccess(['dormitoryApply'=>$dormitoryApply]);
    }

    public function dormitoryApply() : Response
    {
        $validate = Validate::rule([
            'uuid|用户' => 'require',
            'dormitory_id|宿舍楼' => 'require',
            'student_dormitory_id|宿舍' => 'require'
        ]);
        if (!$validate->check(input('post.'))) {
            return $this->buildFailed(ReturnCode::PARAM_INVALID, $validate->getError());
        }
        $dormitory_id = input('post.dormitory_id/d');
        $student_dormitory_id = input('post.student_dormitory_id/d');
        $reason = input('post.reason');

        $staff = AdminStaff::where([
            'is_delete' => 0,
            'status' => AdminStaff::AUDIT_PASS,
            'uuid' => input('post.uuid/s'),
        ])->find();
        if (!$staff) {
            return $this->buildFailed(ReturnCode::RECORD_NOT_FOUND, '账号不存在或未审核通过');
        }
        if ($staff->type == 0 && $staff->expire_flag) {
            return $this->buildFailed(ReturnCode::AUTH_ERROR, '账号已过期，无法登录');
        }

        $dormitoryApply = AdminStaffDormitoryApply::where([
            'staff_id' => $staff->id,
            'apply_status' => 0
        ])->find();
        if ($dormitoryApply){
            return $this->buildFailed(ReturnCode::DATA_EXISTS, '已在申请变更中，无法重复申请变更');
        }

        $card = AdminStaffIcCard::where([
            'staff_id' => $staff->id,
            'school_id' => $staff->school_id,
            'is_delete' => 0
        ])->find();
        $old_dormitory_id = null;
        $old_student_dormitory_id = null;
        if ($card) {
            $old_dormitory_id = $card->dormitory_id;
            $old_student_dormitory_id = $card->student_dormitory_id;
            if($old_student_dormitory_id == $student_dormitory_id) {
                return $this->buildFailed(ReturnCode::DATA_EXISTS, '变更宿舍与当前宿舍一致');
            }
        }
        // 南华工贸不审核
        if($staff->getAttr('school_id') == 22) {
            // 直接变更宿舍
            $selectedArr = ['id' => $student_dormitory_id, 'permission' => [0,1,2,3]];
            StudentModel::lockAuthorization([$selectedArr], $staff->id);
            // 生成记录
            AdminStaffDormitoryApply::create([
                'school_id' => $staff->school_id,
                'staff_id' => $staff->id,
                'old_dormitory_id' => $old_dormitory_id,
                'old_student_dormitory_id' => $old_student_dormitory_id,
                'dormitory_id' => $dormitory_id,
                'student_dormitory_id' => $student_dormitory_id,
                'apply_time' => time(),
                'apply_status' => 1,
                'refuse_reason' => '系统自动通过'
            ]);
        } else {
            // 生成记录
            AdminStaffDormitoryApply::create([
                'school_id' => $staff->school_id,
                'staff_id' => $staff->id,
                'old_dormitory_id' => $old_dormitory_id,
                'old_student_dormitory_id' => $old_student_dormitory_id,
                'dormitory_id' => $dormitory_id,
                'student_dormitory_id' => $student_dormitory_id,
                'apply_time' => time(),
                'apply_reason' => $reason,
                'apply_status' => 0
            ]);
        }
        return $this->buildSuccess([]);
    }
}